home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / ADVANCED / COMP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  4.6 KB  |  183 lines

  1.  
  2. /* comp.c - by David Blythe, SGI */
  3.  
  4. /* Porter/Duff compositing operations using OpenGL alpha blending. */
  5.  
  6. /* NOTE:  This program uses OpenGL blending functions that need the    frame
  7.    buffer to retain a destination alpha component.  Examples of such
  8.    hardware:  O2, IMPACT, RealityEngine, and InfiniteReality. */
  9.  
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <math.h>
  13. #include <GL/glut.h>
  14. #include "texture.h"
  15.  
  16. static int w = 640, h = 640;
  17.  
  18. void
  19. myReshape(int nw, int nh)
  20. {
  21.   w = nw, h = nh;
  22.   glClearColor(0, 0, 0, 0);
  23.   glViewport(0, 0, w, h);
  24.   glMatrixMode(GL_PROJECTION);
  25.   glLoadIdentity();
  26.   glMatrixMode(GL_MODELVIEW);
  27.   glLoadIdentity();
  28. }
  29.  
  30. static unsigned *a_data = 0, *b_data = 0;
  31. static int a_width, a_height, b_width, b_height;
  32.  
  33. void
  34. init_tris(void)
  35. {
  36.   if (a_data)
  37.     free(a_data);
  38.   if (b_data)
  39.     free(b_data);
  40.   a_data = (unsigned *) malloc(w * h);
  41.   b_data = (unsigned *) malloc(w * h);
  42.   glViewport(0, 0, w / 2, h / 2);
  43.   glClear(GL_COLOR_BUFFER_BIT);
  44.   glColor4f(1, 0, 0, 1);
  45.   glBegin(GL_TRIANGLES);
  46.   glVertex2f(-1, -1);
  47.   glVertex2f(-1, 1);
  48.   glVertex2f(.5, 1);
  49.   glEnd();
  50.   glReadPixels(0, 0, w / 2, h / 2, GL_RGBA, GL_UNSIGNED_BYTE, a_data);
  51.  
  52.   glClear(GL_COLOR_BUFFER_BIT);
  53.   glColor4f(0, 1, 0, 1);
  54.   glBegin(GL_TRIANGLES);
  55.   glVertex2f(1, -1);
  56.   glVertex2f(1, 1);
  57.   glVertex2f(-.5, 1);
  58.   glEnd();
  59.   glReadPixels(0, 0, w / 2, h / 2, GL_RGBA, GL_UNSIGNED_BYTE, b_data);
  60.  
  61.   a_width = b_width = w / 2, a_height = b_height = h / 2;
  62. }
  63.  
  64. void
  65. init_images(void)
  66. {
  67.   int comp;
  68.  
  69.   a_data = read_texture("a.rgb", &a_width, &a_height, &comp);
  70.   printf("%dx%dx%d\n", a_width, a_height, comp);
  71.   b_data = read_texture("b.rgb", &b_width, &b_height, &comp);
  72.   printf("%dx%dx%d\n", b_width, b_height, comp);
  73. }
  74.  
  75. void
  76. display(void)
  77. {
  78.   int i;
  79.  
  80.   glDrawBuffer(GL_FRONT_AND_BACK);
  81.   glClear(GL_COLOR_BUFFER_BIT);
  82.   glDrawBuffer(GL_BACK);
  83.  
  84.   glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
  85.   /* image A */
  86.   glViewport(0, 0, w / 2, h / 2);
  87.   glRasterPos2f(-1, -1);
  88.   glDrawPixels(a_width, a_height, GL_RGBA, GL_UNSIGNED_BYTE,
  89.     a_data);
  90.   glEnable(GL_BLEND);
  91.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
  92.   glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR);
  93.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  94.   glDisable(GL_BLEND);
  95.  
  96.   /* image B */
  97.   glViewport(w / 2, 0, w / 2, h / 2);
  98.   glRasterPos2f(-1, -1);
  99.   glDrawPixels(b_width, b_height, GL_RGBA, GL_UNSIGNED_BYTE,
  100.     b_data);
  101.   glEnable(GL_BLEND);
  102.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
  103.   glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR);
  104.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  105.   glReadBuffer(GL_BACK);
  106.   glDrawBuffer(GL_FRONT);
  107.  
  108.   for (i = 0; i < 4; i++) {
  109.     glDisable(GL_BLEND);
  110.     switch (i) {
  111.     case 0:            /* a over b */
  112.       glViewport(0, 0, w / 2, h / 2);
  113.       glRasterPos2f(-1, -1);
  114.       glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR);
  115.       glEnable(GL_BLEND);
  116.       glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
  117.       glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR);
  118.       break;
  119.     case 1:            /* a under b */
  120.       glViewport(w / 2, 0, w / 2, h / 2);
  121.       glRasterPos2f(-1, -1);
  122.       glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR);
  123.       glEnable(GL_BLEND);
  124.       glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  125.       glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR);
  126.       break;
  127.     case 2:            /* b in a */
  128.       glViewport(0, h / 2, w / 2, h / 2);
  129.       glRasterPos2f(-1, -1);
  130.       glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR);
  131.       glEnable(GL_BLEND);
  132.       glBlendFunc(GL_DST_ALPHA, GL_ZERO);
  133.       glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR);
  134.       break;
  135.     case 3:            /* b out of a */
  136.       glViewport(w / 2, h / 2, w / 2, h / 2);
  137.       glRasterPos2f(-1, -1);
  138.       glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR);
  139.       glEnable(GL_BLEND);
  140.       glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO);
  141.       glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR);
  142.       break;
  143.     }
  144.   }
  145.   glViewport(0, 0, w, h);
  146.   glEnable(GL_BLEND);
  147.   glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
  148.   glColor4f(1., 1., 1., 0.);
  149.   glRectf(-1, -1, 1, 1);
  150.   glFlush();
  151. }
  152.  
  153. /* ARGSUSED1 */
  154. void
  155. key(unsigned char key, int x, int y)
  156. {
  157.   if (key == '\033')
  158.     exit(0);
  159. }
  160.  
  161. int
  162. main(int argc, char *argv[])
  163. {
  164.   glutInit(&argc, argv);
  165.   glutInitWindowSize(w, h);
  166.   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA);
  167.   if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE)) {
  168.     printf("comp: requires a frame buffer with destination alpha\n");
  169.     exit(1);
  170.   }
  171.   glutCreateWindow("comp");
  172.  
  173.   if (argc > 1)
  174.     init_images();
  175.   else
  176.     init_tris();
  177.   glutDisplayFunc(display);
  178.   glutReshapeFunc(myReshape);
  179.   glutKeyboardFunc(key);
  180.   glutMainLoop();
  181.   return 0;             /* ANSI C requires main to return int. */
  182. }
  183.